package com.sttg.csp.common.struts;

import java.io.InputStream;
import java.io.OutputStream;

import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.dispatcher.StrutsResultSupport;

import com.opensymphony.xwork2.ActionInvocation;

/**
 * 做了如下改动:<li>1.修改webwork默认的stream类型结果处理类为此类</li> <li>
 * 2.为此类增加了中文文件名的处理</li> <br>
 * <!-- START SNIPPET: description --> A custom Result type for send raw data
 * (via an InputStream) directly to the HttpServletResponse. Very useful for
 * allowing users to download content. <!-- END SNIPPET: description -->
 * <p/>
 * <b>This result type takes the following parameters:</b> <!-- START SNIPPET:
 * params -->
 * <ul>
 * <li><b>contentType</b> - the stream mime-type as sent to the web browser
 * (default = <code>text/plain</code>).</li>
 * <li><b>contentLength</b> - the stream length in bytes (the browser displays a
 * progress bar).</li>
 * <li><b>contentDispostion</b> - the content disposition header value for
 * specifing the file name (default = <code>inline</code>, values are typically
 * <i>filename="document.pdf"</i>.</li>
 * <li><b>inputName</b> - the name of the InputStream property from the chained
 * action (default = <code>inputStream</code>).</li>
 * <li><b>bufferSize</b> - the size of the buffer to copy from input to output
 * (default = <code>1024</code>).</li>
 * </ul>
 * <!-- END SNIPPET: params --> <b>Example:</b>
 * 
 * <pre>
 *         &lt;!-- START SNIPPET: example --&gt;
 *         &lt;result name=&quot;success&quot; type=&quot;stream&quot;&gt;
 *         &lt;param name=&quot;contentType&quot;&gt;image/jpeg&lt;/param&gt;
 *         &lt;param name=&quot;inputName&quot;&gt;imageStream&lt;/param&gt;
 *         &lt;param name=&quot;contentDisposition&quot;&gt;filename=&quot;document.pdf&quot;&lt;/param&gt;
 *         &lt;param name=&quot;bufferSize&quot;&gt;1024&lt;/param&gt;
 *         &lt;/result&gt;
 *         &lt;!-- END SNIPPET: example --&gt;
 * </pre>
 * 
 * *
 * 
 * @author mcrawford
 * @author Rainer Hermanns
 */
public class StreamResult extends StrutsResultSupport {
	/**
	 * 
	 */
	private static final long serialVersionUID = -5209866281891456040L;

	protected String contentType = "text/plain";

	protected int contentLength;

	protected String contentDisposition = "inline";

	protected String inputName = "inputStream";

	protected int bufferSize = 1024;

	/**
	 * @return Returns the bufferSize.
	 */
	public int getBufferSize() {
		return (bufferSize);
	}

	/**
	 * @param bufferSize
	 *            The bufferSize to set.
	 */
	public void setBufferSize(int bufferSize) {
		this.bufferSize = bufferSize;
	}

	/**
	 * @return Returns the contentType.
	 */
	public String getContentType() {
		return (contentType);
	}

	/**
	 * @param contentType
	 *            The contentType to set.
	 */
	public void setContentType(String contentType) {
		this.contentType = contentType;
	}

	/**
	 * @return Returns the contentLength.
	 */
	public int getContentLength() {
		return contentLength;
	}

	/**
	 * @param contentLength
	 *            The contentLength to set.
	 */
	public void setContentLength(int contentLength) {
		this.contentLength = contentLength;
	}

	/**
	 * @return Returns the Content-disposition header value.
	 */
	public String getContentDisposition() {
		return contentDisposition;
	}

	/**
	 * @param contentDisposition
	 *            the Content-disposition header value to use.
	 */
	public void setContentDisposition(String contentDisposition) {
		this.contentDisposition = contentDisposition;
	}

	/**
	 * @return Returns the inputName.
	 */
	public String getInputName() {
		return (inputName);
	}

	/**
	 * @param inputName
	 *            The inputName to set.
	 */
	public void setInputName(String inputName) {
		this.inputName = inputName;
	}

	/**
	 * @see com.opensymphony.xwork.Result#execute(com.opensymphony.xwork.ActionInvocation)
	 */
	protected void doExecute(String finalLocation, ActionInvocation invocation)
			throws Exception {

		InputStream oInput = null;
		OutputStream oOutput = null;

		try {
			// Find the inputstream from the invocation variable stack
			String input = conditionalParse(inputName, invocation);
			oInput = (InputStream) invocation.getStack().findValue(input);

			// Find the Response in context
			HttpServletResponse oResponse = (HttpServletResponse) invocation
					.getInvocationContext().get(HTTP_RESPONSE);

			// Set the content type
			//oResponse.setContentType(conditionalParse(contentType, invocation));

			// Set the content length
			if (contentLength != 0) {
				oResponse.setContentLength(contentLength);
			}

			// Set the content-disposition
			if (contentDisposition != null) {
				/**
				 * 处理中文文件名称
				 */
				String Content_disposition = conditionalParse(
						contentDisposition, invocation);
				oResponse.addHeader("Content-Disposition", new String(
						Content_disposition.getBytes("GB2312"), "ISO8859_1"));
			}

			// Get the outputstream
			oOutput = oResponse.getOutputStream();

			// Copy input to output
			byte[] oBuff = new byte[bufferSize];
			int iSize = 0;
			while (-1 != (iSize = oInput.read(oBuff))) {
				oOutput.write(oBuff, 0, iSize);
			}

			oResponse.setStatus(HttpServletResponse.SC_OK);
			// Flush
			oOutput.flush();
		} finally {
			if (oInput != null)
				oInput.close();
			if (oOutput != null)
				oOutput.close();
		}
	}

}
